home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / pyshared / launchpadbugs / storeblob.py < prev    next >
Encoding:
Python Source  |  2009-03-12  |  3.1 KB  |  94 lines

  1. '''Temporarily store a blob in Launchpad and get a ticket for it.
  2.  
  3. Copyright (C) 2007 Canonical Ltd.
  4. Author: Martin Pitt <martin.pitt@ubuntu.com>
  5.  
  6. This program is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU General Public License as published by the
  8. Free Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  See http://www.gnu.org/copyleft/gpl.html for
  10. the full text of the license.
  11. '''
  12.  
  13. import multipartpost_handler, urllib2, time, httplib
  14. import socket
  15.  
  16. _https_upload_callback = None
  17.  
  18. #
  19. # This progress code is based on KodakLoader by Jason Hildebrand
  20. # <jason@opensky.ca>. See http://www.opensky.ca/~jdhildeb/software/kodakloader/
  21. # for details.
  22. class HTTPSProgressConnection(httplib.HTTPSConnection):
  23.     '''Implement a HTTPSConnection with an optional callback function for
  24.     upload progress.'''
  25.  
  26.     def send(self, data):
  27.         global _https_upload_callback
  28.  
  29.         # if callback has not been set, call the old method
  30.         if not _https_upload_callback:
  31.             httplib.HTTPSConnection.send(self, data)
  32.             return
  33.  
  34.         sent = 0
  35.         total = len(data)
  36.         chunksize = 1024
  37.         while sent < total:
  38.             _https_upload_callback(sent, total)
  39.             t1 = time.time()
  40.             httplib.HTTPSConnection.send(self, data[sent:sent+chunksize])
  41.             sent += chunksize
  42.             t2 = time.time()
  43.  
  44.             # adjust chunksize so that it takes between .5 and 2 
  45.             # seconds to send a chunk
  46.             if t2 - t1 < .5:
  47.                 chunksize *= 2
  48.             elif t2 - t1 > 2:
  49.                 chunksize /= 2
  50.  
  51. class HTTPSProgressHandler(urllib2.HTTPSHandler):
  52.  
  53.     def https_open(self, req):
  54.         return self.do_open(HTTPSProgressConnection, req)
  55.  
  56.  
  57. def upload(blob, progress_callback = None, staging=False):
  58.     '''Upload given blob (file-like object) to Malone and return the ticket for
  59.     it.
  60.  
  61.     progress_callback can be set to a function(sent, total) which is regularly
  62.     called with the number of bytes already sent and total number of bytes to
  63.     send. It is called every 0.5 to 2 seconds (dynamically adapted to upload
  64.     bandwidth).
  65.  
  66.     Return None on error.
  67.  
  68.     By default this uses the production Launchpad instance. Set staging=True to
  69.     use staging.launchpad.net (for testing).
  70.     '''
  71.     
  72.     # working around LP: #314212
  73.     # python-apt sets a 2 seconds timeout in jaunty which results in
  74.     # failing uploads. To workaround this temporary set timeout to None
  75.     # (no timeout)
  76.     old_timeout = socket.getdefaulttimeout()
  77.     socket.setdefaulttimeout(30)
  78.     ticket = None
  79.  
  80.     global _https_upload_callback
  81.     _https_upload_callback = progress_callback
  82.  
  83.     opener = urllib2.build_opener(HTTPSProgressHandler, multipartpost_handler.MultipartPostHandler)
  84.     if staging:
  85.         url = 'https://staging.launchpad.net/+storeblob'
  86.     else:
  87.         url = 'https://launchpad.net/+storeblob'
  88.     result = opener.open(url,
  89.         { 'FORM_SUBMIT': '1', 'field.blob': blob })
  90.     ticket = result.info().get('X-Launchpad-Blob-Token')
  91.     socket.setdefaulttimeout(old_timeout)
  92.  
  93.     return ticket
  94.